home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / varie / uae-0_64.lha / uae-0.6.4 / src / cia.c < prev    next >
C/C++ Source or Header  |  1996-08-14  |  16KB  |  744 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * CIA chip support
  5.   *
  6.   * Copyright 1995 Bernd Schmidt, Alessandro Bissacco
  7.   * Copyright 1996 Stefan Reinauer
  8.   */
  9.  
  10. #include "sysconfig.h"
  11. #include "sysdeps.h"
  12. #include <assert.h>
  13.  
  14. #include "config.h"
  15. #include "options.h"
  16. #include "events.h"
  17. #include "memory.h"
  18. #include "custom.h"
  19. #include "cia.h"
  20. #include "disk.h"
  21. #include "xwin.h"
  22. #include "keybuf.h"
  23. #include "gui.h"
  24.  
  25. #define DIV10 5 /* Yes, a bad identifier. */
  26.  
  27. /* battclock stuff */
  28. #define RTC_D_ADJ      8
  29. #define RTC_D_IRQ      4
  30. #define RTC_D_BUSY     2
  31. #define RTC_D_HOLD     1
  32. #define RTC_E_t1       8
  33. #define RTC_E_t0       4
  34. #define RTC_E_INTR     2
  35. #define RTC_E_MASK     1
  36. #define RTC_F_TEST     8
  37. #define RTC_F_24_12    4
  38. #define RTC_F_STOP     2
  39. #define RTC_F_RSET     1
  40.  
  41. static UBYTE clock_control_d = RTC_D_ADJ + RTC_D_HOLD;
  42. static UBYTE clock_control_e = 0;
  43. static UBYTE clock_control_f = RTC_F_24_12;
  44.  
  45. static UBYTE ciaaicr,ciaaimask,ciabicr,ciabimask;
  46. static UBYTE ciaacra,ciaacrb,ciabcra,ciabcrb;
  47. static ULONG ciaata,ciaatb,ciabta,ciabtb;
  48. static UWORD ciaala,ciaalb,ciabla,ciablb;
  49. static ULONG ciaatod,ciabtod,ciaatol,ciabtol,ciaaalarm,ciabalarm;
  50. static int ciaatodon, ciabtodon;
  51. static int ciaatlatch,ciabtlatch;
  52. static UBYTE ciaapra,ciaaprb,ciaadra,ciaadrb,ciaasdr;
  53. static UBYTE ciabpra,ciabprb,ciabdra,ciabdrb,ciabsdr; 
  54. static int div10;
  55. static int kbstate, kback;
  56.  
  57. static int prtopen;
  58. static FILE *prttmp;
  59.  
  60. static void setclr(UBYTE *p, UBYTE val)
  61. {
  62.     if (val & 0x80) {
  63.     *p |= val & 0x7F;
  64.     } else {
  65.     *p &= ~val;
  66.     }
  67. }
  68.  
  69. static void RethinkICRA(void)
  70. {
  71.     if (ciaaimask & ciaaicr) {
  72.     ciaaicr |= 0x80;
  73.     custom_bank.wput(0xDFF09C,0x8008);
  74.     } else {
  75.     ciaaicr &= 0x7F;
  76. /*    custom_bank.wput(0xDFF09C,0x0008);*/
  77.     }
  78. }
  79.  
  80. static void RethinkICRB(void)
  81. {
  82. #if 0 /* ??? What's this then? */
  83.     if (ciabicr & 0x10) {
  84.     custom_bank.wput(0xDFF09C,0x9000);
  85.     }
  86. #endif
  87.     if (ciabimask & ciabicr) {
  88.     ciabicr |= 0x80;
  89.     custom_bank.wput(0xDFF09C,0xA000);
  90.     } else {
  91.     ciabicr &= 0x7F;
  92. /*    custom_bank.wput(0xDFF09C,0x2000);*/
  93.     }
  94. }
  95.  
  96. static int lastdiv10;
  97.  
  98. static void CIA_update(void)
  99. {
  100.     unsigned long int ccount = cycles - eventtab[ev_cia].oldcycles + lastdiv10;
  101.     unsigned long int ciaclocks = ccount / DIV10;
  102.  
  103.     int aovfla = 0, aovflb = 0, bovfla = 0, bovflb = 0;
  104.  
  105.     lastdiv10 = div10;
  106.     div10 = ccount % DIV10;
  107.     
  108.     /* CIA A timers */
  109.     if ((ciaacra & 0x21) == 0x01) {
  110.     assert((ciaata+1) >= ciaclocks);
  111.     if ((ciaata+1) == ciaclocks) {
  112.         aovfla = 1;
  113.         if ((ciaacrb & 0x61) == 0x41) {
  114.         if (ciaatb-- == 0) aovflb = 1;        
  115.         }
  116.     }         
  117.     ciaata -= ciaclocks;
  118.     }
  119.     if ((ciaacrb & 0x61) == 0x01) {
  120.     assert((ciaatb+1) >= ciaclocks);
  121.     if ((ciaatb+1) == ciaclocks) aovflb = 1;
  122.     ciaatb -= ciaclocks;
  123.     }
  124.     
  125.     /* CIA B timers */
  126.     if ((ciabcra & 0x21) == 0x01) {
  127.     assert((ciabta+1) >= ciaclocks);
  128.     if ((ciabta+1) == ciaclocks) {
  129.         bovfla = 1;
  130.         if ((ciabcrb & 0x61) == 0x41) {
  131.         if (ciabtb-- == 0) bovflb = 1;
  132.         }
  133.     } 
  134.     ciabta -= ciaclocks;
  135.     }
  136.     if ((ciabcrb & 0x61) == 0x01) {
  137.     assert ((ciabtb+1) >= ciaclocks);
  138.     if ((ciabtb+1) == ciaclocks) bovflb = 1;
  139.     ciabtb -= ciaclocks;
  140.     }
  141.     if (aovfla) {
  142.     ciaaicr |= 1; RethinkICRA();
  143.     ciaata = ciaala;
  144.     if (ciaacra & 0x8) ciaacra &= ~1;
  145.     }
  146.     if (aovflb) {
  147.     ciaaicr |= 2; RethinkICRA();
  148.     ciaatb = ciaalb;
  149.     if (ciaacrb & 0x8) ciaacrb &= ~1;
  150.     }
  151.     if (bovfla) {
  152.     ciabicr |= 1; RethinkICRB();
  153.     ciabta = ciabla;
  154.     if (ciabcra & 0x8) ciabcra &= ~1;
  155.     }
  156.     if (bovflb) {
  157.     ciabicr |= 2; RethinkICRB();
  158.     ciabtb = ciablb;
  159.     if (ciabcrb & 0x8) ciabcrb &= ~1;
  160.     }
  161. }
  162.  
  163. static void CIA_calctimers(void)
  164. {
  165.     int ciaatimea = -1, ciaatimeb = -1, ciabtimea = -1, ciabtimeb = -1;
  166.  
  167.     eventtab[ev_cia].oldcycles = cycles;
  168.     
  169.     if ((ciaacra & 0x21) == 0x01) {
  170.     ciaatimea = (DIV10-div10) + DIV10*ciaata;    
  171.     }
  172.     if ((ciaacrb & 0x61) == 0x41) {
  173.     /* Timer B will not get any pulses if Timer A is off. */
  174.     if (ciaatimea >= 0) {
  175.         /* If Timer A is in one-shot mode, and Timer B needs more than
  176.          * one pulse, it will not underflow. */
  177.         if (ciaatb == 0 || (ciaacra & 0x8) == 0) {
  178.         /* Otherwise, we can determine the time of the underflow. */
  179.         ciaatimeb = ciaatimea + ciaala * DIV10 * ciaatb;
  180.         }
  181.     }
  182.     }
  183.     if ((ciaacrb & 0x61) == 0x01) {
  184.     ciaatimeb = (DIV10-div10) + DIV10*ciaatb;
  185.     }
  186.  
  187.     if ((ciabcra & 0x21) == 0x01) {
  188.     ciabtimea = (DIV10-div10) + DIV10*ciabta;    
  189.     }
  190.     if ((ciabcrb & 0x61) == 0x41) {
  191.     /* Timer B will not get any pulses if Timer A is off. */
  192.     if (ciabtimea >= 0) {
  193.         /* If Timer A is in one-shot mode, and Timer B needs more than
  194.          * one pulse, it will not underflow. */
  195.         if (ciabtb == 0 || (ciabcra & 0x8) == 0) {
  196.         /* Otherwise, we can determine the time of the underflow. */
  197.         ciabtimeb = ciabtimea + ciabla * DIV10 * ciabtb;
  198.         }
  199.     }
  200.     }
  201.     if ((ciabcrb & 0x61) == 0x01) {
  202.     ciabtimeb = (DIV10-div10) + DIV10*ciabtb;
  203.     }
  204.     eventtab[ev_cia].active = (ciaatimea != -1 || ciaatimeb != -1
  205.                    || ciabtimea != -1 || ciabtimeb != -1);
  206.     if (eventtab[ev_cia].active) {
  207.     unsigned long int ciatime = ~0L;
  208.     if (ciaatimea != -1) ciatime = ciaatimea;
  209.     if (ciaatimeb != -1 && ciaatimeb < ciatime) ciatime = ciaatimeb;
  210.     if (ciabtimea != -1 && ciabtimea < ciatime) ciatime = ciabtimea;
  211.     if (ciabtimeb != -1 && ciabtimeb < ciatime) ciatime = ciabtimeb;
  212.     eventtab[ev_cia].evtime = ciatime + cycles;
  213.     }
  214.     events_schedule();
  215. }
  216.  
  217. void CIA_handler(void)
  218. {
  219.     CIA_update();
  220.     CIA_calctimers();
  221. }
  222.  
  223. void diskindex_handler(void)
  224. {
  225.     eventtab[ev_diskindex].evtime += cycles - eventtab[ev_diskindex].oldcycles;
  226.     eventtab[ev_diskindex].oldcycles = cycles;
  227. /*    printf(".\n");*/
  228.     ciabicr |= 0x10;
  229.     RethinkICRB();
  230. }
  231.  
  232. void CIA_hsync_handler(void)
  233. {
  234.     static int keytime = 0;
  235.  
  236.     if (ciabtodon)
  237.     ciabtod++;
  238.     ciabtod &= 0xFFFFFF;
  239.  
  240.     if (ciabtod == ciabalarm) {
  241.     ciabicr |= 4; RethinkICRB();
  242.     }
  243.     if (keys_available() && kback && (++keytime & 15) == 0) {
  244.     switch(kbstate) {
  245.      case 0:
  246.         ciaasdr = (BYTE)~0xFB; /* aaarghh... stupid compiler */
  247.         kbstate++;
  248.         break;
  249.      case 1:
  250.         kbstate++;
  251.         ciaasdr = (BYTE)~0xFD;
  252.         break;
  253.      case 2:
  254.         ciaasdr = ~get_next_key();
  255.         break;
  256.     }
  257.     ciaaicr |= 8; RethinkICRA();
  258.     }
  259. }
  260.  
  261. void CIA_vsync_handler()
  262. {    
  263.     if (ciaatodon) 
  264.     ciaatod++;
  265.     ciaatod &= 0xFFFFFF;
  266.     if (ciaatod == ciaaalarm) {
  267.     ciaaicr |= 4; RethinkICRA();
  268.     }
  269. }
  270.  
  271. static UBYTE ReadCIAA(UWORD addr)
  272. {
  273.     UBYTE tmp;
  274.     
  275.     switch(addr & 0xf){
  276.      case 0: 
  277.     tmp = (DISK_status() & 0x3C);
  278.     if (!buttonstate[0]) tmp |= 0x40;
  279.     if (!joy0button) tmp |= 0x80;
  280.     return tmp;
  281.      case 1:
  282.     return ciaaprb;
  283.      case 2:
  284.     return ciaadra;
  285.      case 3:
  286.     return ciaadrb;
  287.      case 4:
  288.     return ciaata & 0xff;
  289.      case 5:
  290.     return ciaata >> 8;
  291.      case 6:
  292.     return ciaatb & 0xff;
  293.      case 7:
  294.     return ciaatb >> 8;
  295.      case 8:
  296.     if (ciaatlatch) {
  297.         ciaatlatch = 0;
  298.         return ciaatol & 0xff;
  299.     } else return ciaatod & 0xff;
  300.      case 9:
  301.     if (ciaatlatch) return (ciaatol >> 8) & 0xff;
  302.     else return (ciaatod >> 8) & 0xff;
  303.      case 10:
  304.     ciaatlatch = 1; ciaatol = ciaatod; /* ??? only if not already latched? */
  305.     return (ciaatol >> 16) & 0xff;
  306.      case 12:
  307.     return ciaasdr;
  308.      case 13:
  309.     tmp = ciaaicr; ciaaicr = 0; RethinkICRA(); return tmp;
  310.      case 14:
  311.     return ciaacra;
  312.      case 15:
  313.     return ciaacrb;
  314.     }
  315.     return 0;
  316. }
  317.  
  318. static UBYTE ReadCIAB(UWORD addr)
  319. {
  320.     UBYTE tmp;
  321.     
  322.     switch(addr & 0xf){
  323.      case 0: 
  324.         fprintf (stderr,"ciabpra (Modem Register) read: 0x%02x\n",ciabpra);
  325.     return ciabpra;
  326.      case 1:
  327.     return ciabprb;
  328.      case 2:
  329.     return ciabdra;
  330.      case 3:
  331.     return ciabdrb;
  332.      case 4:
  333.     return ciabta & 0xff;
  334.      case 5:
  335.     return ciabta >> 8;
  336.      case 6:
  337.     return ciabtb & 0xff;
  338.      case 7:
  339.     return ciabtb >> 8;
  340.      case 8:
  341.     if (ciabtlatch) {
  342.         ciabtlatch = 0;
  343.         return ciabtol & 0xff;
  344.     } else return ciabtod & 0xff;
  345.      case 9:
  346.     if (ciabtlatch) return (ciabtol >> 8) & 0xff;
  347.     else return (ciabtod >> 8) & 0xff;
  348.      case 10:
  349.     ciabtlatch = 1; ciabtol = ciabtod;
  350.     return (ciabtol >> 16) & 0xff;
  351.      case 12:
  352.     return ciabsdr;
  353.      case 13:
  354.     tmp = ciabicr; ciabicr = 0; RethinkICRB();
  355.     return tmp;
  356.      case 14:
  357.     return ciabcra;
  358.      case 15:
  359.     return ciabcrb;
  360.     }
  361.     return 0;
  362. }
  363.  
  364. static void WriteCIAA(UWORD addr,UBYTE val)
  365. {
  366.     int oldled;
  367.     switch(addr & 0xf){
  368.      case 0:
  369.     oldled = ciaapra & 2;
  370.     ciaapra = (ciaapra & ~0x3) | (val & 0x3); LED(ciaapra & 0x2);
  371.     if ((ciaapra & 2) != oldled)
  372.         gui_led (0, !(ciaapra & 2));
  373.     break;
  374.      case 1:
  375.     ciaaprb = val;
  376.     if (prtopen==1) {
  377. #ifndef __DOS__
  378.         fprintf (prttmp,"%c",val);
  379. #else
  380.         fputc (val, prttmp);
  381.         fflush (prttmp);
  382. #endif
  383.         if (val==0x04) {
  384. #if defined(__unix) && !defined(__bebox__) && !defined(__DOS__)
  385.         pclose (prttmp);
  386. #else
  387.         fclose (prttmp);
  388. #endif
  389.         prtopen = 0;
  390.         }
  391.         } else {
  392. #if defined(__unix) && !defined(__bebox__) && !defined(__DOS__)
  393.             prttmp=(FILE *)popen ((char *)prtname,"w");
  394. #else
  395.             prttmp=(FILE *)fopen ((char *)prtname,"wb");
  396. #endif
  397.         if (prttmp != NULL) {
  398.         prtopen = 1;
  399. #ifndef __DOS__
  400.         fprintf (prttmp,"%c",val);
  401. #else
  402.         fputc (val, prttmp);
  403.         fflush (prttmp);
  404. #endif
  405.         }
  406.         }
  407.     ciaaicr |= 0x10;
  408.     break;
  409.      case 2:
  410.     ciaadra = val; break;
  411.      case 3:
  412.     ciaadrb = val; break;
  413.      case 4:
  414.     CIA_update();
  415.     ciaala = (ciaala & 0xff00) | val;
  416.     CIA_calctimers();
  417.     break;
  418.      case 5:
  419.     CIA_update();
  420.     ciaala = (ciaala & 0xff) | (val << 8);
  421.     if ((ciaacra & 1) == 0)
  422.         ciaata = ciaala;
  423.     if (ciaacra & 8) { 
  424.         ciaata = ciaala; 
  425.         ciaacra |= 1; 
  426.     }
  427.     CIA_calctimers();
  428.     break;
  429.      case 6:
  430.     CIA_update();
  431.     ciaalb = (ciaalb & 0xff00) | val;
  432.     CIA_calctimers();
  433.     break;
  434.      case 7:
  435.     CIA_update();
  436.     ciaalb = (ciaalb & 0xff) | (val << 8);
  437.     if ((ciaacrb & 1) == 0)
  438.         ciaatb = ciaalb;
  439.     if (ciaacrb & 8) { 
  440.         ciaatb = ciaalb;
  441.         ciaacrb |= 1; 
  442.     }
  443.     CIA_calctimers();
  444.     break;
  445.      case 8:
  446.     if (ciaacrb & 0x80){
  447.         ciaaalarm = (ciaaalarm & ~0xff) | val;
  448.     } else {
  449.         ciaatod = (ciaatod & ~0xff) | val;
  450.         ciaatodon = 1;
  451.     }
  452.     break;
  453.      case 9:
  454.     if (ciaacrb & 0x80){
  455.         ciaaalarm = (ciaaalarm & ~0xff00) | (val << 8);
  456.     } else {
  457.         ciaatod = (ciaatod & ~0xff00) | (val << 8);
  458.         ciaatodon = 0;
  459.     }
  460.     break;
  461.      case 10:
  462.     if (ciaacrb & 0x80){
  463.         ciaaalarm = (ciaaalarm & ~0xff0000) | (val << 16);
  464.     } else {
  465.         ciaatod = (ciaatod & ~0xff0000) | (val << 16);
  466.         ciaatodon = 0;
  467.     }
  468.     break;
  469.      case 12:
  470.     ciaasdr = val; break;
  471.      case 13:
  472.     setclr(&ciaaimask,val); break; /* ??? call RethinkICR() ? */
  473.      case 14:
  474.     CIA_update();
  475.     ciaacra = val;
  476.     if (ciaacra & 0x10){
  477.         ciaacra &= ~0x10;
  478.         ciaata = ciaala;
  479.     }
  480.     if (ciaacra & 0x40) {
  481.         kback = 1;
  482.     }
  483.     CIA_calctimers();
  484.     break;
  485.      case 15:
  486.     CIA_update();
  487.     ciaacrb = val; 
  488.     if (ciaacrb & 0x10){
  489.         ciaacrb &= ~0x10;
  490.         ciaatb = ciaalb;
  491.     }
  492.     CIA_calctimers();
  493.     break;
  494.     }
  495. }
  496.  
  497. static void WriteCIAB(UWORD addr,UBYTE val)
  498. {
  499.     switch(addr & 0xf){
  500.      case 0:
  501.     ciabpra = (ciabpra & ~0x3) | (val & 0x3); break;
  502.      case 1:
  503.     ciabprb = val; DISK_select(val); break;
  504.      case 2:
  505.     ciabdra = val; break;
  506.      case 3:
  507.     ciabdrb = val; break;
  508.      case 4:
  509.     CIA_update();
  510.     ciabla = (ciabla & 0xff00) | val;
  511.     CIA_calctimers();
  512.     break;
  513.      case 5:
  514.     CIA_update();
  515.     ciabla = (ciabla & 0xff) | (val << 8);
  516.     if ((ciabcra & 1) == 0) 
  517.         ciabta = ciabla;
  518.     if (ciabcra & 8) {
  519.         ciabta = ciabla; 
  520.         ciabcra |= 1; 
  521.     } 
  522.     CIA_calctimers();
  523.     break;
  524.      case 6:
  525.     CIA_update();
  526.     ciablb = (ciablb & 0xff00) | val;
  527.     CIA_calctimers();
  528.     break;
  529.      case 7:
  530.     CIA_update();
  531.     ciablb = (ciablb & 0xff) | (val << 8);
  532.     if ((ciabcrb & 1) == 0)
  533.         ciabtb = ciablb;
  534.     if (ciabcrb & 8) {
  535.         ciabtb = ciablb;
  536.         ciabcrb |= 1;
  537.     }
  538.     CIA_calctimers();
  539.     break;
  540.      case 8:
  541.     if (ciabcrb & 0x80){
  542.         ciabalarm = (ciabalarm & ~0xff) | val;
  543.     } else {
  544.         ciabtod = (ciabtod & ~0xff) | val;
  545.         ciabtodon = 1;
  546.     }
  547.     break;
  548.      case 9:
  549.     if (ciabcrb & 0x80){
  550.         ciabalarm = (ciabalarm & ~0xff00) | (val << 8);
  551.     } else {
  552.         ciabtod = (ciabtod & ~0xff00) | (val << 8);
  553.         ciabtodon = 0;
  554.     }
  555.     break;
  556.      case 10:
  557.     if (ciabcrb & 0x80){
  558.         ciabalarm = (ciabalarm & ~0xff0000) | (val << 16);
  559.     } else {
  560.         ciabtod = (ciabtod & ~0xff0000) | (val << 16);
  561.         ciabtodon = 0;
  562.     }
  563.     break;
  564.      case 12:
  565.     ciabsdr = val; 
  566.     break;
  567.      case 13:
  568.     setclr(&ciabimask,val); 
  569.     break;
  570.      case 14:
  571.     CIA_update();
  572.     ciabcra = val;
  573.     if (ciabcra & 0x10){
  574.         ciabcra &= ~0x10;
  575.         ciabta = ciabla;
  576.     }
  577.     CIA_calctimers();
  578.     break;
  579.      case 15:
  580.     CIA_update();
  581.     ciabcrb = val; 
  582.     if (ciabcrb & 0x10){
  583.         ciabcrb &= ~0x10;
  584.         ciabtb = ciablb;
  585.     }
  586.     CIA_calctimers();
  587.     break;
  588.     }
  589. }
  590.  
  591. void CIA_reset(void)
  592. {
  593.     kback = 1;
  594.     kbstate = 0;
  595.     
  596.     ciaatlatch = ciabtlatch = 0;
  597.     ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0;
  598.     ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
  599.     ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; /* outmode = toggle; */
  600.     ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF;
  601.     div10 = 0;
  602.     lastdiv10 = 0;
  603.     CIA_calctimers();
  604.  
  605.     ciabpra = 0xDC;
  606. }
  607.  
  608. void dumpcia(void)
  609. {
  610.     printf("A: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx, TB: %04lx\n",
  611.        (int)ciaacra, (int)ciaacrb, (int)ciaaimask, ciaatod, 
  612.        ciaatlatch ? " latched" : "", ciaata, ciaatb);
  613.     printf("B: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx, TB: %04lx\n",
  614.        (int)ciabcra, (int)ciabcrb, (int)ciabimask, ciabtod, 
  615.        ciabtlatch ? " latched" : "", ciabta, ciabtb);
  616. }
  617.  
  618. /* CIA memory access */
  619.  
  620. static ULONG cia_lget(CPTR) REGPARAM;
  621. static UWORD cia_wget(CPTR) REGPARAM;
  622. static UBYTE cia_bget(CPTR) REGPARAM;
  623. static void  cia_lput(CPTR, ULONG) REGPARAM;
  624. static void  cia_wput(CPTR, UWORD) REGPARAM;
  625. static void  cia_bput(CPTR, UBYTE) REGPARAM;
  626.  
  627. addrbank cia_bank = {
  628.     default_alget, default_awget,
  629.     cia_lget, cia_wget, cia_bget,
  630.     cia_lput, cia_wput, cia_bput,
  631.     default_xlate, default_check
  632. };
  633.  
  634. ULONG cia_lget(CPTR addr)
  635. {
  636.     return cia_bget(addr+3);
  637. }
  638.  
  639. UWORD cia_wget(CPTR addr)
  640. {
  641.     return cia_bget(addr+1);
  642. }
  643.  
  644. UBYTE cia_bget(CPTR addr)
  645. {
  646.     if ((addr & 0x3001) == 0x2001)
  647.         return ReadCIAA((addr & 0xF00) >> 8);
  648.     if ((addr & 0x3001) == 0x1000)
  649.         return ReadCIAB((addr & 0xF00) >> 8);
  650.     return 0;
  651. }
  652.  
  653. void cia_lput(CPTR addr, ULONG value)
  654. {
  655.     cia_bput(addr+3,value); /* FIXME ? */
  656. }
  657.  
  658. void cia_wput(CPTR addr, UWORD value)
  659. {
  660.     cia_bput(addr+1,value);
  661. }
  662.  
  663. void cia_bput(CPTR addr, UBYTE value)
  664. {
  665.     if ((addr & 0x3001) == 0x2001)
  666.         WriteCIAA((addr & 0xF00) >> 8,value);
  667.     if ((addr & 0x3001) == 0x1000)
  668.         WriteCIAB((addr & 0xF00) >> 8,value);
  669. }
  670.  
  671. /* battclock memory access */
  672.  
  673. static ULONG clock_lget(CPTR) REGPARAM;
  674. static UWORD clock_wget(CPTR) REGPARAM;
  675. static UBYTE clock_bget(CPTR) REGPARAM;
  676. static void  clock_lput(CPTR, ULONG) REGPARAM;
  677. static void  clock_wput(CPTR, UWORD) REGPARAM;
  678. static void  clock_bput(CPTR, UBYTE) REGPARAM;
  679.  
  680. addrbank clock_bank = {
  681.     default_alget, default_awget,
  682.     clock_lget, clock_wget, clock_bget,
  683.     clock_lput, clock_wput, clock_bput,
  684.     default_xlate, default_check
  685. };
  686.  
  687. ULONG clock_lget(CPTR addr)
  688. {
  689.     return clock_bget(addr+3);
  690. }
  691.  
  692. UWORD clock_wget(CPTR addr)
  693. {
  694.     return clock_bget(addr+1);
  695. }
  696.  
  697. UBYTE clock_bget(CPTR addr)
  698. {
  699.     time_t t=time(0);
  700.     struct tm *ct;
  701.     ct=localtime(&t);
  702.     switch (addr & 0x3f)
  703.     {
  704.      case 0x03: return ct->tm_sec % 10;
  705.      case 0x07: return ct->tm_sec / 10;
  706.      case 0x0b: return ct->tm_min % 10;
  707.      case 0x0f: return ct->tm_min / 10;
  708.      case 0x13: return ct->tm_hour % 10;
  709.      case 0x17: return ct->tm_hour / 10;
  710.      case 0x1b: return ct->tm_mday % 10;
  711.      case 0x1f: return ct->tm_mday / 10;
  712.      case 0x23: return (ct->tm_mon+1) % 10;
  713.      case 0x27: return (ct->tm_mon+1) / 10;
  714.      case 0x2b: return ct->tm_year % 10;
  715.      case 0x2f: return ct->tm_year / 10;
  716.  
  717.      case 0x33: return ct->tm_wday;  /*Hack by -=SR=- */
  718.      case 0x37: return clock_control_d;
  719.      case 0x3b: return clock_control_e;
  720.      case 0x3f: return clock_control_f;
  721.     }
  722.     return 0;
  723. }
  724.  
  725. void clock_lput(CPTR addr, ULONG value)
  726. {
  727.     /* No way */
  728. }
  729.  
  730. void clock_wput(CPTR addr, UWORD value)
  731. {
  732.     /* No way */
  733. }
  734.  
  735. void clock_bput(CPTR addr, UBYTE value)
  736. {
  737.     switch (addr & 0x3f)
  738.     {
  739.      case 0x37: clock_control_d=value; break;
  740.      case 0x3b: clock_control_e=value; break;
  741.      case 0x3f: clock_control_f=value; break;
  742.     }
  743. }
  744.